package com.advert.presentation.tools;

import com.advert.config.Config;
import com.advert.config.MailConfig;
import com.advert.model.security.*;
import com.advert.model.security.Role;
import com.advert.model.support.*;
import com.advert.presentation.util.EntityComparator;
import com.advert.presentation.util.InitParameter;
import com.advert.presentation.util.InitParameters;
import com.advert.service.security.SecurityService;
import com.advert.service.xml.XmlBindingService;
import com.advert.presentation.util.localization.ConstantContainer;
import com.advert.presentation.util.localization.Label;
import com.advert.presentation.util.localization.LabelsMap;
import com.advert.service.support.SupportService;
import org.jboss.seam.ScopeType;
import org.jboss.seam.annotations.*;
import org.jboss.seam.log.Log;

import java.io.File;
import java.text.Collator;
import java.util.*;

@Name("applicationFactory")
@Scope(ScopeType.APPLICATION)
public class ApplicationFactory {
    @Logger
    private Log logger;

    @In("facesHelper")
    private FacesHelper facesHelper;
    @In(value = "SupportService")
    private SupportService supportService;
    @In(value = "XmlBindingService")
    private XmlBindingService xmlBindingService;
    @In("SecurityService")
    private SecurityService securityService;
    @In("initParams")
    private InitParameters initParameters;
    

    @Factory(value = "labels", autoCreate = true)
    public LabelsMap getLabelsMap() {
        Map<String, Label> map = new HashMap<String, Label>();
        ConstantContainer constantContainer = xmlBindingService.unmarshal(ConstantContainer.class, facesHelper.getExternalContext().getResourceAsStream(initParameters.get(InitParameter.LOCALIZATION_FILE)));
        for (Label label : constantContainer.getLabels()) {
            map.put(label.getId(), label);
        }
        return new LabelsMap(map);
    }

    @Factory(value = "ctxPath", autoCreate = true)
    public String getContextPath() {
        return facesHelper.getExternalContext().getRequestContextPath();
    }

    @Factory(value = "productTypes", autoCreate = true)
    public List<ProductType> getProductTypes() {
        return Arrays.asList(ProductType.values());
    }

    @Factory(value = "vehicleTypes", autoCreate = true)
    public List<VehicleTypeEntity> getVehicleTypes() {
        List<VehicleTypeEntity> retVal = supportService.getVehicleTypes();
        Collections.sort(retVal, new EntityComparator(getLabelsMap()));
        return retVal;
    }

    @Factory(value = "vehicleCategories", autoCreate = true)
    public Map<String, List<VehicleCategoryEntity>> getVehicleCategories() {
        Map<String, List<VehicleCategoryEntity>> retVal = supportService.getVehicleCategories();
        for (List<VehicleCategoryEntity> vehicleCategoryEntities : retVal.values()) {
            Collections.sort(vehicleCategoryEntities, new EntityComparator(getLabelsMap()));    
        }
        return retVal;
    }

    @Factory(value = "vehicleBrands", autoCreate = true)
    public Map<String, List<VehicleBrandEntity>> getVehicleBrands() {
        Map<String, List<VehicleBrandEntity>> retVal = supportService.getVehicleBrands();
        for (String s : retVal.keySet()) {
            if (s != null) {
                List<VehicleBrandEntity> brands = retVal.get(s);
                brands.addAll(retVal.get(null));
                Collections.sort(brands, new EntityComparator(getLabelsMap()));
            }
        }
        return retVal;
    }

    @Factory(value = "vehicleStates", autoCreate = true)
    public List<VehicleStateEntity> getVehicleStates() {
        return supportService.getVehicleStates();
    }

    @Factory(value = "regions", autoCreate = true)
    public List<RegionEntity> getRegions() {
        List<RegionEntity> retVal = supportService.getRegions();
        Collections.sort(retVal, new EntityComparator(getLabelsMap()));
        return retVal;
    }

    @Factory(value = "years", autoCreate = true)
    public List<Integer> getYears() {
        List<Integer> retVal = new ArrayList<Integer>();
        int currentYear = Calendar.getInstance().get(Calendar.YEAR);
        for (int i = 0; i < 100; i++) {
            retVal.add(currentYear - i);
        }
        return retVal;
    }

    @Factory(value = "currencies", autoCreate = true)
    public List<CurrencyEntity> getCurrencies() {
        List<CurrencyEntity> retVal = supportService.getCurrencies();
        Collections.sort(retVal, new EntityComparator(getLabelsMap()));
        return retVal;
    }

    @Factory(value = "initParams", autoCreate = true)
    @SuppressWarnings("unchecked")
    public InitParameters getInitParameters() {
        return new InitParameters(facesHelper.getExternalContext().getInitParameterMap());
    }

    @Factory(value = "uploadedImagesDirectory", autoCreate = true)
    public File getDirectory() {
        String directoryPath = facesHelper.getServletContext().getRealPath(getConfig().getImageConfig().getUploadedUri());
        return new File(directoryPath);
    }

    @Factory(value = "config", autoCreate = true)
    public Config getConfig() {
        return xmlBindingService.unmarshal(Config.class, facesHelper.getExternalContext().getResourceAsStream(initParameters.get(InitParameter.CONFIG_FILE)));
    }

    @Factory(value = "securityCollection", autoCreate = true)
    public Map<String, Map<com.advert.model.security.Role, Map<AccessType,SecurityEntity>>> getSecurityCollection() {
        return securityService.getSecurityCollection();
    }

    @Factory(value = "userRoles", autoCreate = true)
    public List<Role> getUserRoles() {
        List<Role> retVal = Arrays.asList(Role.values());
        Collections.sort(retVal, new EntityComparator(getLabelsMap()));
        return retVal;
    }
}
